package MathCore.Operators;

import MathCore.Lexeme;
import MathCore.Operand;
import MathCore.Operands.*;
import MathCore.Real;

/**
 *
 * @author Александр
 */
public class ComplexFunction extends Function
{
    public static final int CMP		=1;
    public static final int CMPE	=2;
    public static final int RE		=3;
    public static final int IM		=4;
    public static final int ARG		=5;

	public ComplexFunction(int type)
	{
		this.type = type;
	}

	public Operand exec(Operand[] operands) throws OperatorException
	{
		if(operands.length != params())
			throw new OperatorException("Неправильное количество операндов у функции "+toString()+". Необходимо "+params()+".");

		if(have(operands, List.class))
		{
			return expandListsLinear(operands, this);
		}
		else if(only(operands, Number.class))
		{
			switch(type)
			{
				case CMP:  return new Complex(((Number)operands[0]).get(), ((Number)operands[1]).get(), Complex.RE_IM);
				case CMPE: return new Complex(((Number)operands[0]).get(), ((Number)operands[1]).get(), Complex.ABS_ARG);
			}
			
			throw new OperatorException(OperatorException.UNSUPPORTED_COMBINATION);
		}
		else if(only(operands, Complex.class))
		{
			Complex cmp = (Complex) operands[0];
			switch(type)
			{
				case RE: return new Number(cmp.Re());
				case IM: return new Number(cmp.Im());
				case ARG: return new Number(cmp.arg());
			}
			
			throw new OperatorException(OperatorException.UNSUPPORTED_COMBINATION);
		}
		else
		{
			throw new OperatorException(OperatorException.UNSUPPORTED_COMBINATION);
		}
	}

    public int params() 
	{
		switch(type)
		{
			case CMP:
			case CMPE:
				return 2;
				
			case RE:
			case IM:
			case ARG:
				return 1;
		}
		return 0;
    }

    public String toString() 
	{
		switch(type)
		{
			case CMP:	return "cmp";
			case CMPE:	return "cmpe";
			case RE:	return "re";
			case IM:	return "im";
			case ARG:	return "arg";
		}
		return "";
    }

    public Lexeme clone() 
	{
		return new ComplexFunction(type);
    }
}
